﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;

namespace EzDesk.DevHelper.HtmlToAspx
{
    public class EzCssAndJsConverter : EzTfsConverter
    {
        private string rootFolder;

        private const string SourcePathFormat = @"DevHelper\EzDesk.DevHelper.HtmlDev\HtmlDev\html\{0}";
        private const string DestPathFormat = @"Clients\EzDesk.Clients.DesktopWeb\{0}";

        private const string SourcePathBase = @"DevHelper\EzDesk.DevHelper.HtmlDev\HtmlDev\html\";
        private const string DestPathBase = @"Clients\EzDesk.Clients.DesktopWeb\";

        private const string JsCommonFilePath = @"Clients\EzDesk.Clients.DesktopWeb\Scripts\ezdesk_common.js";
        private const string JsMockFilePath = @"Clients\EzDesk.Clients.DesktopWeb\Scripts\ezdesk_mockdata.js";

        public EzCssAndJsConverter(string rootFolder)
        {
            this.rootFolder = rootFolder;
        }

        public void Convert()
        {
            // 1. 把文件复制过去
            copyFilesToDest();

            // 2. 修改 ez_common中 js 相对路径
            string commonJsFileName = Path.Combine(rootFolder, JsCommonFilePath);
            string commonJspattern = "import\\(\"scripts";
            string commonJsreplacement = "import(\"../../scripts";
            replaceFileContentByRegex(commonJsFileName, commonJspattern, commonJsreplacement);

            // 3. 修改 ez_mockdata中 isMock属性
            string mockJsFileName = Path.Combine(rootFolder, JsMockFilePath);
            string mockJspattern = "IS_MOCKED : true,";
            string mockJsreplacement = "IS_MOCKED : false,";
            replaceFileContentByRegex(mockJsFileName, mockJspattern, mockJsreplacement);

        }

        private void replaceFileContentByRegex(
            string commonJsFileName, 
            string pattern, 
            string replacement
            )
        {
            
            string fileContent = "";
            using (var sr = new StreamReader(commonJsFileName))
            {
                fileContent = sr.ReadToEnd();
            }
            fileContent = Regex.Replace(fileContent, pattern, replacement);
            
            resetFileReadonly(commonJsFileName);

            using (var sw = new StreamWriter(commonJsFileName, false))
            {
                sw.WriteLine(fileContent);
            }
        }

        /// <summary>
        /// 去掉文件的只读属性
        /// </summary>
        /// <param name="fileName"></param>
        private void resetFileReadonly(string fileName)
        {
            var fi = new FileInfo(fileName);
            if (fi.Attributes.ToString().IndexOf("ReadOnly") != -1)
            {
                File.SetAttributes(fileName, FileAttributes.Normal);
            }
        }

        public override List<string> SourceFiles()
        {
            return getAllSourceFileList();
        }

        public override string GetDestFile(string sourceFile)
        {
            return getDestFileName(sourceFile);
        }
        

        #region [ private methods ]


        private void copyFilesToDest()
        {
            var sourceFileList = getAllSourceFileList();

            //copy文件
            foreach (var sourceFile in sourceFileList)
            {
                var destFileName = getDestFileName(sourceFile);
                // 目标文件夹不存在，创建一个！
                var destPath = Path.GetDirectoryName(destFileName);
                if (destPath != null)
                {
                    if (!Directory.Exists(destPath))
                    {
                        Directory.CreateDirectory(destPath);
                    }
                    // 删除只读文件
                    if (File.Exists(destFileName))
                    {
                        resetFileReadonly(destFileName);
                    }
                }
                else
                {
                    throw new ArgumentException("错误的目标文件名");
                }
                File.Copy(sourceFile, destFileName, true);
            }
        }


        private string getDestFileName(string sourceFile)
        {
            string sourcePath = SourcePathBase;
            string destPath = DestPathBase;
            return sourceFile.Replace(sourcePath, destPath);
        }

        private List<string> getAllDestFileList()
        {
            List<string> scriptsFiles = getDestFiles("Scripts");
            List<string> contentFiles = getDestFiles("content");

            var fileList = new List<string>();
            fileList.AddRange(scriptsFiles);
            fileList.AddRange(contentFiles);

            return fileList;
        }

        private List<string> getAllSourceFileList()
        {
            List<string> scriptsFiles = getSourceFiles("Scripts");
            List<string> contentFiles = getSourceFiles("content");

            var fileList = new List<string>();
            fileList.AddRange(scriptsFiles);
            fileList.AddRange(contentFiles);

            return fileList;
        }


        private List<string> getSourceFiles(string signal)
        {
            string sourcePath =
                string.Format(
                    SourcePathFormat,
                    signal
                    );

            List<string> sourceFiles = getFiles(sourcePath);
            return sourceFiles;
        }

        private List<string> getDestFiles(string signal)
        {
            string sourcePath =
                string.Format(
                    SourcePathFormat,
                    signal
                    );

            List<string> sourceFiles = getFiles(sourcePath);

            string destPath =
                string.Format(
                    DestPathFormat, 
                    signal
                    );
            return sourceFiles
                .Select(t => getDestFileName(t))
                .ToList();
        }



        private List<string> getFiles(string sourcePath)
        {
            string sourceFullPath = Path.Combine(rootFolder, sourcePath);

            List<string> sourceFiles = getFilesRecursion(sourceFullPath);
            return sourceFiles;
        }

        private List<string> getFilesRecursion(string path)
        {
            var result = new List<string>();
            result.AddRange(
                Directory.GetFiles(path)
                );
            var dirs = Directory.GetDirectories(path);
            foreach (var dir in dirs)
            {
                result.AddRange(getFilesRecursion(dir));
            }

            return result;
        }
        #endregion



    }
}
